/*================================================================================
*
*
*                                                     
*
*
* 项目名称: mcp2515-spi-can-demo
* 文件名称: mcp2515.h
* 创建日期: 20-12-21
* 文件描述: 
*
================================================================================*/
#ifndef INC_MCP2515_H_
#define INC_MCP2515_H_

#include <stdint.h>

//-MCP2515 寄存器地址枚举-
typedef enum tagMCP2515Register
{
    RXF0SIDH,
    RXF0SIDL,
    RXF0EID8,
    RXF0EID0,
    RXF1SIDH,
    RXF1SIDL,
    RXF1EID8,
    RXF1EID0,
    RXF2SIDH,
    RXF2SIDL,
    RXF2EID8,
    RXF2EID0,
    BFPCTRL,
    TXRTSCTRL,
    CANSTAT,
    CANCTRL,
    
    RXF3SIDH,
    RXF3SIDL,
    RXF3EID8,
    RXF3EID0,
    RXF4SIDH,
    RXF4SIDL,
    RXF4EID8,
    RXF4EID0,
    RXF5SIDH,
    RXF5SIDL,
    RXF5EID8,
    RXF5EID0,
    TEC,
    REC,
    CANSTAT_SAME1,
    CANCTRL_SAME1,
    
    RXM0SIDH,
    RXM0SIDL,
    RXM0EID8,
    RXM0EID0,
    RXM1SIDH,
    RXM1SIDL,
    RXM1EID8,
    RXM1EID0,
    CNF3,
    CNF2,
    CNF1,
    CANINTE,
    CANINTF,
    EFLG,
    CANSTAT_SAME2,
    CANCTRL_SAME2,

    TXB0CTRL,
    TXB0SIDH,
    TXB0SIDL,
    TXB0EID8,
    TXB0EID0,
    TXB0DLC,
    TXB0D0,
    TXB0D1,
    TXB0D2,
    TXB0D3,
    TXB0D4,
    TXB0D5,
    TXB0D6,
    TXB0D7,
    CANSTAT_SAME3,
    CANCTRL_SAME3,
    
    TXB1CTRL,
    TXB1SIDH,
    TXB1SIDL,
    TXB1EID8,
    TXB1EID0,
    TXB1DLC,
    TXB1D0,
    TXB1D1,
    TXB1D2,
    TXB1D3,
    TXB1D4,
    TXB1D5,
    TXB1D6,
    TXB1D7,
    CANSTAT_SAME4,
    CANCTRL_SAME4,
    
    TXB2CTRL,
    TXB2SIDH,
    TXB2SIDL,
    TXB2EID8,
    TXB2EID0,
    TXB2DLC,
    TXB2D0,
    TXB2D1,
    TXB2D2,
    TXB2D3,
    TXB2D4,
    TXB2D5,
    TXB2D6,
    TXB2D7,
    CANSTAT_SAME5,
    CANCTRL_SAME5,
    
    RXB0CTRL,
    RXB0SIDH,
    RXB0SIDL,
    RXB0EID8,
    RXB0EID0,
    RXB0DLC,
    RXB0D0,
    RXB0D1,
    RXB0D2,
    RXB0D3,
    RXB0D4,
    RXB0D5,
    RXB0D6,
    RXB0D7,
    CANSTAT_SAME6,
    CANCTRL_SAME6,
    
    RXB1CTRL,
    RXB1SIDH,
    RXB1SIDL,
    RXB1EID8,
    RXB1EID0,
    RXB1DLC,
    RXB1D0,
    RXB1D1,
    RXB1D2,
    RXB1D3,
    RXB1D4,
    RXB1D5,
    RXB1D6,
    RXB1D7,
    CANSTAT_SAME7,
    CANCTRL_SAME7,
}eMCP2515Reg;

//-MCP2515 CAN V2.0B 消息帧结构体--------------------------------------------------
typedef struct tagMCP2515CANFrame
{
    uint16_t u16SID;        // BIT10:BIT0 -> SID10:SID0
    uint8_t  u8IDE;         // BIT0 -> IDE
    uint32_t u32EID;        // BIT17:BIT0 -> SID17:SID0
    uint8_t  u8RTR;         // BIT0 -> RTR, ETR or RTR judged by IDE
    uint8_t  u8DLC;         // BIT3:BIT0 -> DLC3:DLC0
    uint8_t  u8Data[8];     // u8Data[0]:u8Data[7] -> (TXB0:TXB8)/(RXB0:RXB8)
}McpCanFrm_t;

//SPI INTERFACE------------------------------------------------------------------

#define DEF_SPI_INTERFACE //uncomment this if configured MCU SPI function

#ifdef  DEF_SPI_INTERFACE

//#include "MCU_SPI_PORT"
#include "bsp_mcp2515.h"

#define MCP2515_WR(data)                    MCU_SPI_WRITE_FUNCTION(data)
#define MCP2515_WR_BURST(pdata, amount)     MCU_SPI_WR_BURST_FUNTION(pdata, amount)
#define MCP2515_RD(pdata, amount)           MCU_SPI_READ_FUNCTION(pdata, amount)
#define MCP2515_CS_LO()                     MCU_SPI_CTRL_CS_LO()
#define MCP2515_CS_HI()                     MCU_SPI_CTRL_CS_HI()

#else

#define MCP2515_WR(data)                    ((void)0)
#define MCP2515_WR_BURST(pdata, amount)     ((void)0)
#define MCP2515_RD(pdata, n)                ((void)0)
#define MCP2515_CS_LO()                     ((void)0)
#define MCP2515_CS_HI()                     ((void)0)
#error SPI INTERFACE FOR MCP2515 NOT CONFIGURE!

#endif

//MESSAGE TRANSMISSION-----------------------------------------------------------

#define MCP2515_TXB0_BASE                   TXB0CTRL //TX BUFFER相关寄存器基地址
#define MCP2515_TXB1_BASE                   TXB1CTRL
#define MCP2515_TXB2_BASE                   TXB2CTRL
#define MCP2515_TXB0                        MCP2515_TXB0_BASE
#define MCP2515_TXB1                        MCP2515_TXB1_BASE
#define MCP2515_TXB2                        MCP2515_TXB2_BASE

#define MCP2515_TXP_LVL0                    0 //数字越大优先级越高
#define MCP2515_TXP_LVL1                    1
#define MCP2515_TXP_LVL2                    2
#define MCP2515_TXP_LVL3                    3

typedef enum tagMCP2515TXnRTS_PIN_MOD
{
    MCP2515_RTS_PIN_MOD_DIG_IP,     //数字量数据
    MCP2515_RTS_PIN_MDO_TRIG_TX,    //请求发送
}eMCPRtsPinMod;

extern void MCP2515WrMsgToBuf(uint8_t MCP2515_TXBn, const McpCanFrm_t *pMsg);
extern void MCP2515LdMsgToBuf(uint8_t MCP2515_TXBn, const McpCanFrm_t *pMsg);
extern void MCP2515SetTxPri(uint8_t MCP2515_TXBn, uint8_t MCP2515_TXP_LVLn);
extern void MCP2515RTS(uint8_t MCP2515_TXBn);
extern void MCP2515EnableOSM(void);
extern void MCP2515DisableOSM(void);
extern void MCP2515SetRtsPinMode(uint8_t MCP2515_TXBn, eMCPRtsPinMod MCP2515_RTS_PIN_MODx);
extern uint8_t u8MCP2515GetRtsPinVal(uint8_t MCP2515_TXBn);
extern void MCP2515AbortTx(uint8_t MCP2515_TXBn);

//-CHIP RESET--------------------------------------------------------------------
extern void MCP2515Reset(void);

//-MESSAGE RECEPTION-------------------------------------------------------------
#define MCP2515_RXB0_BASE                   RXB0CTRL
#define MCP2515_RXB1_BASE                   RXB1CTRL
#define MCP2515_RXB0                        MCP2515_RXB0_BASE
#define MCP2515_RXB1                        MCP2515_RXB1_BASE

//-Received Message-
#define MCP2515_MSG_NONE                    0 //No RX message
#define MCP2515_MSG_IN_RXB0                 1 //Message in RXB0
#define MCP2515_MSG_IN_RXB1                 2 //Message in RXB1
#define MCP2515_MSG_IN_BOTH                 4 //Messages in both buffers

//- Msg Type Received-
#define CAN_STD_DATA_FRM                    0 //Standard data frame
#define CAN_STD_REMT_FRM                    1 //Standard remote frame
#define CAN_EXT_DATA_FRM                    2 //Extended data frame
#define CAN_EXT_REMT_FRM                    3 //Extended remote frame

//-Filter Match-
#define MCP2515_FLT_MAT_RXF0                0
#define MCP2515_FLT_MAT_RXF1                1
#define MCP2515_FLT_MAT_RXF2                2
#define MCP2515_FLT_MAT_RXF3                3
#define MCP2515_FLT_MAT_RXF4                4
#define MCP2515_FLT_MAT_RXF5                5
#define MCP2515_FLT_MAT_RXF0_ROV            6 //rollover to RXB1
#define MCP2515_FLT_MAT_RXF1_ROV            7 //rollover to RXB1

//-Receive Buffer Operation Mode-
#define MCP2515_RXMODE0                     0 //接收符合条件的标准帧、扩展帧
#define MCP2515_RXMODE1                     1 //只接收符合滤波条件标准帧
#define MCP2515_RXMODE2                     2 //只接收符合滤波条件扩展帧
#define MCP2515_RXMODE3                     3 //关闭屏蔽/滤波功能

//- RX0BF and RX1BF Pins-
#define MCP2515_RXP_MOD_RXNE_INT            0x01 //RXBn PIN 中断模式
#define MCP2515_RXP_MOD_DIG_OUT0            0x10 //RXBn PIN 数字输出0
#define MCP2515_RXP_MOD_DIG_OUT1            0x00 //RXBn PIN 数字数字1

//-RXFn CAN 滤波器起始地址-
#define MCP2515_RXF0                        RXF0SIDH
#define MCP2515_RXF1                        RXF1SIDH
#define MCP2515_RXF2                        RXF2SIDH
#define MCP2515_RXF3                        RXF3SIDH
#define MCP2515_RXF4                        RXF4SIDH
#define MCP2515_RXF5                        RXF5SIDH

#define MCP2515_RXM0                        RXM0SIDH
#define MCP2515_RXM1                        RXM1SIDH

typedef struct tagRX_STATUS
{
    uint8_t u8RcvdMsg;
    uint8_t u8MsgTyp;
    uint8_t u8FltMtch;
}McpRxStat_t;

typedef struct tagRxFilter
{
    uint16_t u16SID;
    uint8_t  u8EXIDE;
    uint32_t u32EID;
}McpRxFlt_t;

typedef struct tagRxMask
{
    uint16_t u16SID;
    uint32_t u32EID;
}McpRxMsk_t;

extern void MCP2515GetMsg(uint8_t MCP2515_RXBn, McpCanFrm_t *pMsg);
extern void MCP2515GetMatchFLT(McpRxStat_t *pRxStat);
extern void MCP2515EnableROV(void);
extern void MCP2515DisableROV(void);
extern void MCP251SetRXM(uint8_t MCP2515_RXBn, uint8_t MCP2515_RXMn);
extern void MCP2515SetRxPinMode(uint8_t MCP2515_RXBn, uint8_t MCP2515_RXP_MODx);
extern void MCP2515EnalbeRxPin(uint8_t MCP2515_RXBn);
extern void MCP2515DisalbeRxPin(uint8_t MCP2515_RXBn);
extern void MCP2515SetRxFlt(uint8_t MCP2515_RXFn, const McpRxFlt_t *pFilter);
extern void MCP2515SetRxMsk(uint8_t MCP2515_RXMn, const McpRxMsk_t *pMask);

//-BIT TIMING--------------------------------------------------------------------
//-Bit timing configuration registers-
typedef struct tagBitTime
{
    uint8_t u8BRP; //时钟分频
    uint8_t u8PRSEG; //传播段
    uint8_t u8PHSEG1; //PS1
    uint8_t u8PHSEG2; //PS2
    uint8_t u8SJW;
}McpBitTime_t;

extern void MCP2515CfgBitTime(McpBitTime_t *pBitTime);

//-ERROR DETECTION---------------------------------------------------------------
#define MCP2515_ERR_RX1OVR                  (7)
#define MCP2515_ERR_RX0OVR                  (6)
#define MCP2515_ERR_TXB0                    (5)
#define MCP2515_ERR_TXEP                    (4)
#define MCP2515_ERR_RXEP                    (3)
#define MCP2515_ERR_TXWAR                   (2)
#define MCP2515_ERR_RXWAR                   (1)
#define MCP2515_ERR_EWARN                   (0)

/*************
* @brief 
    获取错位标志位，有错误值为1，正常值为0，使用该宏定义前，
    需调用函数MCP2515RdEFLG()获取 MCP2515ErrState
* @param MCP2515_ERR_BIT, 需要的告警位,对应寄存器 EFLG
    @arg MCP2515_ERR_RX1OVR
    @arg MCP2515_ERR_RX0OVR
    @arg MCP2515_ERR_TXB0
    @arg MCP2515_ERR_TXEP
    @arg MCP2515_ERR_RXEP
    @arg MCP2515_ERR_TXWAR
    @arg MCP2515_ERR_RXWAR
    @arg MCP2515_ERR_EWARN
*/
#define MCP2515_GET_ERR_FLAG(MCP2515_ERR_BIT)               (MCP2515ErrState>>MCP2515_ERR_BIT&0x01)

extern uint8_t MCP2515ErrState;

extern void MCP2515RdEFLG(void);

//-INTERRUPTS--------------------------------------------------------------------
//-interrupt enable bit or flag bit-
typedef enum tagMCP2515InterruptBit
{
    MCP2515_IT_RX0=(1<<0),
    MCP2515_IT_RX1=(1<<1),
    MCP2515_IT_TX0=(1<<2),
    MCP2515_IT_TX1=(1<<3),
    MCP2515_IT_TX2=(1<<4),
    MCP2515_IT_ERR=(1<<5),
    MCP2515_IT_WAK=(1<<6),
    MCP2515_IT_MERR=(1<<7),
}eMcpITBit;

extern uint8_t MCP2515ITState;

extern uint8_t u8MCP2515GetICOD(void);
extern void MCP2515EnableIT(eMcpITBit MCP2515_IT_x);
extern void MCP2515DisableIT(eMcpITBit MCP2515_IT_x);
extern uint8_t u8MCP2515RdCANINTE(void);
extern void MCP2515RdITFLG(void);
extern void MCP2515ClrITFLG(eMcpITBit MCP2515_IT_x);

//-OSCILLATOR--------------------------------------------------------------------
#define MCP2515_CLKPRE1                     0
#define MCP2515_CLKPRE2                     1
#define MCP2515_CLKPRE4                     2
#define MCP2515_CLKPRE8                     3

extern void MCP2515ClkoutCfg(uint8_t State, uint8_t MCP2515_CLKPRE);

//-MODES OF OPERATION------------------------------------------------------------
#define MCP2515_REQOP_NORMAL                0
#define MCP2515_REQOP_SLEEP                 1
#define MCP2515_REQOP_LOOPBACK              2
#define MCP2515_REQOP_LISTEN                3
#define MCP2515_REQOP_CONFIG                4

extern void MCP2515SetMode(uint8_t MCP2515_REQOPx);
extern uint8_t u8MCP2515GetMode(void);

#endif
